/**
 * Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
 * 
 * Dual licensed under the MIT and GPL licenses. This basically means you can
 * use this code however you want for free, but don't claim to have written it
 * yourself! Donations always accepted: http://www.JavascriptToolbox.com/donate/
 * 
 * Please do not link to the .js files on javascripttoolbox.com from your site.
 * Copy the files locally to your server instead.
 * 
 */
/* $VERSION: 1.2 */
var Selectbox = {};

Selectbox.hasOptions = function(obj) {
	return (obj != null && typeof (obj.options) != "undefined" && obj.options != null);
};

Selectbox.selectUnselectMatchingOptions = function(obj, regex, which, only) {
	if (window.RegExp) {
		if (!this.hasOptions(obj)) {
			return false;
		}
		var only = !(typeof (only) == "undefined" || only == null);
		var re = new RegExp(regex);
		for ( var i = 0; i < obj.options.length; i++) {
			if (re.test(obj.options[i].text)) {
				obj.options[i].selected = (which == "select");
			} else if (only) {
				obj.options[i].selected = (which == "unselect");
			}
		}
		return true;
	}
	return false;
};

Selectbox.selectOptions = function(obj, regex) {
	return this.selectUnselectMatchingOptions(obj, regex, "select", false);
};

Selectbox.selectOnlyOptions = function(obj, regex) {
	return this.selectUnselectMatchingOptions(obj, regex, "select", true);
};

Selectbox.unselectOptions = function(obj, regex) {
	return this.selectUnselectMatchingOptions(obj, regex, "unselect", false);
};

Selectbox.sort = function(obj) {
	var o = [];
	if (!this.hasOptions(obj)) {
		return false;
	}
	for ( var i = 0; i < obj.options.length; i++) {
		o[o.length] = new Option(obj.options[i].text, obj.options[i].value, obj.options[i].defaultSelected,
				obj.options[i].selected);
	}
	if (o.length == 0) {
		return true;
	}
	o = o.sort(function(a, b) {
		if ((a.text + "") < (b.text + "")) {
			return -1;
		}
		if ((a.text + "") > (b.text + "")) {
			return 1;
		}
		return 0;
	});

	for ( var i = 0; i < o.length; i++) {
		obj.options[i] = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);
	}
	return true;
};

Selectbox.selectAllOptions = function(obj) {
	if (!this.hasOptions(obj)) {
		return false;
	}
	for ( var i = 0; i < obj.options.length; i++) {
		obj.options[i].selected = true;
	}
	return true;
};

Selectbox.moveSelectedOptions = function(from, to) {
	if (!this.hasOptions(from)) {
		return false;
	}
	// Unselect matching options, if required
	if (arguments.length > 3) {
		var regex = arguments[3];
		if (regex != "") {
			if (!this.unselectOptions(from, regex)) {
				return false;
			}
		}
	}
	// Move them over
	for ( var i = 0; i < from.options.length; i++) {
		var o = from.options[i];
		if (o.selected) {
			var index = (!this.hasOptions(to)) ? 0 : to.options.length;
			to.options[index] = new Option(o.text, o.value, false, false);
		}
	}
	// Delete them from original
	for ( var i = (from.options.length - 1); i >= 0; i--) {
		var o = from.options[i];
		if (o.selected) {
			from.options[i] = null;
		}
	}
	if ((arguments.length < 3) || (arguments[2])) {
		this.sort(from);
		this.sort(to);
	}
	from.selectedIndex = to.selectedIndex = -1;
	return true;
};

Selectbox.copySelectedOptions = function(from, to) {
	if (!this.hasOptions(from)) {
		return false;
	}
	var options = new Object();
	if (this.hasOptions(to)) {
		for ( var i = 0; i < to.options.length; i++) {
			options[to.options[i].value] = to.options[i].text;
		}
	}
	for ( var i = 0; i < from.options.length; i++) {
		var o = from.options[i];
		if (o.selected) {
			if (typeof (options[o.value]) == "undefined" || options[o.value] == null || options[o.value] != o.text) {
				var index = (!this.hasOptions(to)) ? 0 : to.options.length;
				to.options[index] = new Option(o.text, o.value, false, false);
			}
		}
	}
	if ((arguments.length < 3) || (arguments[2] == true)) {
		this.sort(to);
	}
	from.selectedIndex = to.selectedIndex = -1;
	return true;
};

Selectbox.moveAllOptions = function(from, to) {
	this.selectAllOptions(from);
	if (arguments.length == 2) {
		this.moveSelectedOptions(from, to);
	} else if (arguments.length == 3) {
		this.moveSelectedOptions(from, to, arguments[2]);
	} else if (arguments.length == 4) {
		this.moveSelectedOptions(from, to, arguments[2], arguments[3]);
	}
};

Selectbox.copyAllOptions = function(from, to) {
	this.selectAllOptions(from);
	if (arguments.length == 2) {
		this.copySelectedOptions(from, to);
	} else if (arguments.length == 3) {
		this.copySelectedOptions(from, to, arguments[2]);
	}
};

Selectbox.swapOptions = function(obj, i, j) {
	if (!this.hasOptions(obj)) {
		return false;
	}
	var o = obj.options;
	if (i < 0 || i >= o.length || j < 0 || j >= o.length) {
		return false;
	}
	var i_selected = o[i].selected;
	var j_selected = o[j].selected;
	var temp = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);
	var temp2 = new Option(o[j].text, o[j].value, o[j].defaultSelected, o[j].selected);
	o[i] = temp2;
	o[j] = temp;
	o[i].selected = j_selected;
	o[j].selected = i_selected;
	return true;
};

Selectbox.moveOptionUp = function(obj) {
	if (!this.hasOptions(obj)) {
		return false;
	}
	for (i = 0; i < obj.options.length; i++) {
		if (obj.options[i].selected) {
			if (i > 0 && !obj.options[i - 1].selected) {
				this.swapOptions(obj, i, i - 1);
				obj.options[i - 1].selected = true;
			}
		}
	}
	return true;
};

Selectbox.moveOptionDown = function(obj) {
	if (!this.hasOptions(obj)) {
		return false;
	}
	for (i = obj.options.length - 1; i >= 0; i--) {
		if (obj.options[i].selected) {
			if (i != (obj.options.length - 1) && !obj.options[i + 1].selected) {
				this.swapOptions(obj, i, i + 1);
				obj.options[i + 1].selected = true;
			}
		}
	}
	return true;
};

Selectbox.removeSelectedOptions = function(from) {
	if (!this.hasOptions(from)) {
		return false;
	}
	if (from.type == "select-one" && from.selectedIndex >= 0) {
		from.options[from.selectedIndex] = null;
	} else {
		for ( var i = (from.options.length - 1); i >= 0; i--) {
			var o = from.options[i];
			if (o.selected) {
				from.options[i] = null;
			}
		}
	}
	from.selectedIndex = -1;
};

Selectbox.removeAllOptions = function(from) {
	if (!this.hasOptions(from)) {
		return false;
	}
	for ( var i = (from.options.length - 1); i >= 0; i--) {
		from.options[i] = null;
	}
	from.selectedIndex = -1;
	return true;
};

Selectbox.addOption = function(obj, text, value, selected) {
	if (obj != null && obj.options != null) {
		obj.options[obj.options.length] = new Option(text, value, false, selected);
	}
};

// Create a jQuery Plugin wrapper around the functions
if (typeof jQuery != "undefined") {
	var fn;
	jQuery.fn.Selectbox = function(fn) {
		return function() {
			var args = Array.prototype.slice.apply(arguments);
			return this.each(function() {
				Selectbox[fn].apply(Selectbox, ( [ this ]).concat(args));
			});
		};
	};
	for (fn in Selectbox) {
		jQuery.fn[(fn == "sort") ? "sortOptions" : fn] = jQuery.fn.Selectbox(fn);
	}
};
